package com.qianfeng.es.service.impl;

//
//                            _ooOoo_  
//                           o8888888o  
//                           88" . "88  
//                           (| -_- |)  
//                            O\ = /O  
//                        ____/`---'\____  
//                      .   ' \\| |// `.  
//                       / \\||| : |||// \  
//                     / _||||| -:- |||||- \  
//                       | | \\\ - /// | |  
//                     | \_| ''\---/'' | |  
//                      \ .-\__ `-` ___/-. /  
//                   ___`. .' /--.--\ `. . __  
//                ."" '< `.___\_<|>_/___.' >'"".  
//               | | : `- \`.;`\ _ /`;.`/ - ` : | |  
//                 \ \ `-. \_ __\ /__ _/ .-` / /  
//         ======`-.____`-.___\_____/___.-`____.-'======  
//                            `=---='  
//  
//         .............................................  
//                  佛祖镇楼                  BUG辟易  
//          佛曰:  
//                  写字楼里写字间，写字间里程序员；  
//                  程序人员写程序，又拿程序换酒钱。  
//                  酒醒只在网上坐，酒醉还来网下眠；  
//                  酒醉酒醒日复日，网上网下年复年。  
//                  但愿老死电脑间，不愿鞠躬老板前；  
//                  奔驰宝马贵者趣，公交自行程序员。  
//                  别人笑我忒疯癫，我笑自己命太贱；  
//  


import com.fasterxml.jackson.databind.ObjectMapper;
import com.qianfeng.es.service.QueryService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.CardinalityAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

/**
 * Created by Jackiechan on 2022/6/20 16:23
 *
 * @author Jackiechan
 * @version 1.0
 * @since 1.0
 */
@Service
public class QueryServiceImpl implements QueryService {

    private RestHighLevelClient client;

    private ObjectMapper objectMapper;

    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Autowired
    public void setRestHighLevelClient(RestHighLevelClient restHighLevelClient) {
        this.client = restHighLevelClient;
    }


    @Override
    public SearchResponse termQuery(String index, String field, String value) throws IOException {
        //创建搜索的请求
//        SearchRequest searchRequest = new SearchRequest(index);
//        //封装有查询条件的对象
//        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//        //设置term查询
//        searchSourceBuilder.query(QueryBuilders.termQuery(field, value));
//        //设置查询条件
//        searchRequest.source(searchSourceBuilder);
//        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
//        return response;
        SearchResponse response = baseQuery(index, QueryBuilders.termQuery(field, value));
        return response;
    }

    @Override
    public SearchResponse termsQuery(String index, String field, String... value) throws IOException {
        SearchResponse response = baseQuery(index, QueryBuilders.termsQuery(field, value));
        return response;
    }

    @Override
    public SearchResponse matchAllQuery(String index) throws IOException {
        return baseQuery(index,QueryBuilders.matchAllQuery());
    }

    @Override
    public SearchResponse matchQuery(String index, String field, String value) throws IOException {
        return baseQuery(index,QueryBuilders.matchQuery(field,value));
    }

    @Override
    public SearchResponse booleanQuery(String index, String field, String value, Operator operator) throws IOException {
        return baseQuery(index,QueryBuilders.matchQuery(field,value).operator(operator));
    }

    @Override
    public SearchResponse multiMatch(String index, String value, String... field) throws IOException {
        return baseQuery(index,QueryBuilders.multiMatchQuery(value,field));
    }

    @Override
    public SearchResponse idsQuery(String index, String... ids) throws IOException {
        return baseQuery(index,QueryBuilders.idsQuery().addIds(ids));
    }

    @Override
    public SearchResponse prefixQuery(String index, String field, String value) throws IOException {
        return baseQuery(index,QueryBuilders.prefixQuery(field,value));
    }

    @Override
    public SearchResponse wildCardQuery(String index, String field, String value) throws IOException {
        return baseQuery(index, QueryBuilders.wildcardQuery(field, value));
    }

    @Override
    public SearchResponse rangeQuery(String index, QueryBuilder queryBuilder) throws IOException {
        return baseQuery(index,queryBuilder);
    }

    @Override
    public SearchResponse createScrollQuery(String index, QueryBuilder queryBuilder, int size) throws IOException {
        //创建搜索的请求
        SearchRequest searchRequest = new SearchRequest(index);
        //设置滚动查询,深分页
        searchRequest.scroll("1m");
        //封装有查询条件的对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置查询条件类型
        searchSourceBuilder.query(queryBuilder);
        searchSourceBuilder.size(size);//设置要返回的数量
        //设置查询条件
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        return response;
    }

    @Override
    public SearchResponse scrollQuery(String scrollId) throws IOException {
        //创建滚动查询的请求
        SearchScrollRequest request = new SearchScrollRequest(scrollId).scroll("1m");
        //查询数据
        SearchResponse response = client.scroll(request, RequestOptions.DEFAULT);
        return response;
    }

    @Override
    public void deleteByQuery(String index, QueryBuilder queryBuilder) throws IOException {
        //创建根据查询删除的请求,并设置查询的条件
        DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index).setQuery(queryBuilder);
        BulkByScrollResponse bulkByScrollResponse = client.deleteByQuery(deleteByQueryRequest,RequestOptions.DEFAULT);
        System.err.println(bulkByScrollResponse);
    }

    @Override
    public void boolQuery(String index, QueryBuilder queryBuilder) throws IOException {
        SearchResponse searchResponse = baseQuery(index, queryBuilder);
        System.err.println(searchResponse);
    }

    @Override
    public SearchResponse highLightQuery(String index, QueryBuilder QueryBuilder, HighlightBuilder highlightBuilder) throws IOException {
        //设置查询条件和高亮条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilder).highlighter(highlightBuilder);
        return baseQuery(index, searchSourceBuilder);
    }

    @Override
    public SearchResponse cardinalityAggre(String index, String field) throws IOException {

        CardinalityAggregationBuilder aggregationBuilder = AggregationBuilders
                //创建聚合的builder 参数是别名
                .cardinality("bieming")
                //设置哪个列作为聚合的列
                .field(field);
        return aggressQuery(index,aggregationBuilder);
    }

    @Override
    public SearchResponse rangeAggre(String index, AggregationBuilder aggregationBuilder) throws IOException {
          return aggressQuery(index,aggregationBuilder);
    }


    /**
     * 因为我们的查询就是条件不一样,所以可以封装出来,只需要传递条件就行了
     * @param index
     * @param queryBuilder
     * @return
     * @throws IOException
     */
    public SearchResponse baseQuery(String index, QueryBuilder queryBuilder) throws IOException {
        //创建搜索的请求
       // SearchRequest searchRequest = new SearchRequest(index);
        //封装有查询条件的对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置查询条件类型
        searchSourceBuilder.query(queryBuilder);
        //设置查询条件
      //  searchRequest.source(searchSourceBuilder);
     //   SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        return baseQuery(index,searchSourceBuilder);
    }


    public SearchResponse baseQuery(String index, SearchSourceBuilder searchSourceBuilder) throws IOException {
        //创建搜索的请求
        SearchRequest searchRequest = new SearchRequest(index);
        //设置查询条件
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        return response;
    }

    public SearchResponse aggressQuery(String index, AggregationBuilder builder) throws IOException {
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //设置聚合
        searchSourceBuilder.aggregation(builder);
        return baseQuery(index, searchSourceBuilder);
    }
}
